/*
 * @Description: 拦截websocket请求，并进行模拟数据返回
 * @Version: 1.0
 * @Autor: wangmeng
 * @Date: 2025-02-16 12:54:20
 * @LastEditors: wamgmeng
 * @LastEditTime: 2025-06-18 15:33:43
 */
// proxy-ws-server.ts
import { WebSocket, WebSocketServer } from 'ws';

const PROXY_PORT = 19823;
// 修改目标地址为原来要连接的地址
const TARGET_URL = 'ws://localhost:19800/ws';

// 修改模拟数据的格式
// 建议使用十六进制表示，并注明每个字段的实际值
const mockData = {
    msg_id: 196,
    // cmd_type: 8,
    // param1: 67328,
    // param2: 1973760,
    // param3: 15,

    // cmd_type: 7,
    // param1: 0,
    // param2: 6619237,//动力电池充电器输入电压:10.1V,动力电池充电器输出电压:10.1V
    // param3: 6553700,//航电电池充电器热点温度：10.0℃，动力电池充电器外部采样温度：10.0℃
    // param4: 90//动力电池充电器输入电流:9.0V

    // cmd_type: 7,
    // param1: 0,                    // 无故障
    // param2: 0x00DC0168,          // 输入电压: 36.0V (0x0168), 输出电压: 22.0V (0x00DC)
    // param3: 0x00280032,          // 热点温度: 50°C (0x0032), 外部温度: 40°C (0x0028)
    // param4: 0x0064,              // 输入电流: 10.0A (0x0064 = 100, 实际值需要除以10)

    // cmd_type: 8,
    // param1: 0x3228,      // 动力电池温度 40℃ (0x28), SOC 50% (0x32)
    // param2: 0x46322823,  // 航电1温度 35℃ (0x23), SOC 50% (0x32), 航电2温度 40℃ (0x28), SOC 70% (0x46)
    // param3: 0x32,        // 空速管加热温度 50℃
    // param4: 0,           // 预留

    // cmd_type: 2,
    // param1: 0x01160320,  // 动力电池电压: 80.0% (0x0320 = 800), 启动电池电压: 27.8V (0x0116 = 278)
    // param2: 0x00000001,  // 充电状态：充电中
    // param3: 0x02BC0384,  // 航电1电压: 90.0% (0x0384 = 900), 航电2电压: 70.0% (0x02BC = 700)
    // param4: 0,           // 预留

    // cmd_type: 7,
    // param1: 0,
    // param2: 6619237, //动力电池充电器输入电压:10.1V,动力电池充电器输出电压:10.1V
    // param3: 6553700, //航电电池充电器热点温度：10.0℃，动力电池充电器外部采样温度：10.0℃
    // param4: 90,


    // cmd_type: 3,
    // param1: 0,//正常，显示绿灯
    // param2: 100,//表示10.0%
    // param3: 265,//表示265rpm
    // param4: 150,

    cmd_type: 1,
    param1: 10



};

// 电池状态
const batteryStateData = {
    msg_id: 196,
    cmd_type: 2,
    param1: 0x01160320,  // 动力电池电压: 80.0% (0x0320 = 800), 启动电池电压: 27.8V (0x0116 = 278)
    param2: 0x00000001,  // 充电状态：充电中
    param3: 0x02BC0384,  // 航电1电压: 90.0% (0x0384 = 900), 航电2电压: 70.0% (0x02BC = 700)
    param4: 0,           // 预留
}

// 电池温度与电量
const batteryTempAndSOCData = {
    msg_id: 196,
    cmd_type: 8,
    param1: 0x3228,      // 动力电池温度 40℃ (0x28), SOC 50% (0x32)
    param2: 0x46322823,  // 航电1温度 35℃ (0x23), SOC 50% (0x32), 航电2温度 40℃ (0x28), SOC 70% (0x46)
    param3: 0x32,        // 空速管加热温度 50℃
    param4: 0,           // 预留
}


// 发动机启动状态
const startupStateData = {
    msg_id: 196,
    // 启动状态数据 (cmd_type=100)
    cmd_type: 100,
    param1: 0b000000
}

// 发动机温度和燃油压力数据
const engineTempAndFuelData = {
    "msg_id": 196,
    "cmd_type": 90,
    // 50度和120度
    "param1": (120 << 16) | (50 & 0xffff),
    // bit0-bit15燃油压力: 500kPa
    "param2": 500,
}

// 燃油与航时
const fuelAndFlightTimeData = {
    "msg_id": 196,
    "cmd_type": 5,
    "param1": 36021,//显示为10:00:21
    "param2": 101,
    "param3": 2650,
    "param4": 90,
}

// 充电器状态2
const chargerState2Data = {
    "msg_id": 196,
    "cmd_type": 7,
    "param1": 0,
    "param2": 6619237,//动力电池充电器输入电压:10.1V,动力电池充电器输出电压:10.1V
    "param3": 6553700,//航电电池充电器热点温度：10.0℃，动力电池充电器外部采样温度：10.0℃
    "param4": 90
}

// 动力电池充电器状态
const chargerStateData = {
    msg_id: 196,
    cmd_type: 6,
    param1: 1,
    param2: 6619237,//航电电池充电器输入电压:10.1V,航电电池充电器输出电压:10.1V
    param3: 100,
    param4: 90
}

// 航电电池充电器状态
const batteryChargerStateData = {
    msg_id: 196,
    cmd_type: 7,
    param1: 1,
    param2: 6619237,//航电电池充电器输入电压:10.1V,航电电池充电器输出电压:10.1V
    param3: 100,
    param4: 90
}

// 发动机转速
const engineSpeedData = {
    msg_id: 196,
    cmd_type: 3,
    param1: 0,//正常，显示绿灯
    param2: 100,//表示10.0%
    param3: 265,//表示265rpm
    param4: 150,
}

// 雷达信息
const radarData = {
    "msg_id": 91,
    "pps_mode": 1,
    "lidar_mode": 1,
    "record_mode": 1,
    "motor_speed": 3600,
    "return_wave_type": 0
}

// 接管状态 // {"device_id": 1,"flag": 1 }
const takeoverData = {
    "msg_id": 194,
    "cmd": 0,
    "data": "AQE="
}

// // {"device_id": 2,"flag": 0 }
const takeoverData2 = {
    "msg_id": 194,
    "cmd": 0,
    "data": "AgA="
}

// {"device_id": 2,"flag": 1 }
const takeoverData3 = {
    "msg_id": 194,
    "cmd": 0,
    "data": "AgE="
}

// 生成组合导航数据的函数
const generateNavData = () => {
    // 创建二进制数据缓冲区 - 根据字段数量分配足够的空间
    const buffer = Buffer.alloc(100); // 分配足够大的空间
    let offset = 0;

    /* 
1: imu1; 2: imu2; 3: imu3;
11: mag1; 12: mag2; 13: mag3;
21: laser1; 22: laser2; 23: laser3; 
31: airspeed1; 32: airspeed2; 33: airspeed3; 
41: slam1; 51: baro1; 52: baro2;
61: radar1; 62: radar2;
71: gps1; 72: gps2; 73: gps3; 74: gpsheading;
    */


    // 写入各个字段数据
    buffer.writeUInt8(1, offset++);                // status: 正常
    buffer.writeUInt8(71, offset++);                // gps_sel: GPS1
    buffer.writeUInt8(12, offset++);                // mag_sel: MAG1
    buffer.writeUInt8(3, offset++);                // imu_sel: IMU1
    buffer.writeUInt8(31, offset++);                // ias_sel: 空速计1
    buffer.writeUInt8(41, offset++);                // slam_sel: 不使用SLAM
    buffer.writeUInt8(45, offset++);               // mag_earth_standard: 45uT
    buffer.writeUInt8(43, offset++);               // mag_earth_measure: 43uT
    buffer.writeUInt8(5, offset++);                // wind_speed: 5m/s
    buffer.writeInt16LE(120, offset);              // wind_heading: 120度
    offset += 2;
    buffer.writeInt16LE(25, offset);               // dgx: 0.25deg/sec (25/100)
    offset += 2;
    buffer.writeInt16LE(15, offset);               // dgy: 0.15deg/sec (15/100)
    offset += 2;
    buffer.writeInt16LE(10, offset);               // dgz: 0.10deg/sec (10/100)
    offset += 2;
    buffer.writeInt16LE(20, offset);               // dax: 0.20m/sec^2 (20/100)
    offset += 2;
    buffer.writeInt16LE(18, offset);               // day: 0.18m/sec^2 (18/100) (注意：原字段名有错误，应为day而不是第二个dgy)
    offset += 2;
    buffer.writeInt16LE(22, offset);               // daz: 0.22m/sec^2 (22/100) (注意：原字段名有错误，应为daz而不是dgz)
    offset += 2;

    // 北向速度
    buffer.writeInt16LE(500, offset);              // vn_gps1: 5.00m/sec (500/100)
    offset += 2;
    buffer.writeInt16LE(505, offset);              // vn_gps2: 5.05m/sec (505/100)
    offset += 2;
    buffer.writeInt16LE(502, offset);              // vn_nav: 5.02m/sec (502/100)
    offset += 2;
    buffer.writeInt16LE(0, offset);                // vn_slam: 0m/sec
    offset += 2;

    // 东向速度
    buffer.writeInt16LE(300, offset);              // ve_gps1: 3.00m/sec (300/100)
    offset += 2;
    buffer.writeInt16LE(305, offset);              // ve_gps2: 3.05m/sec (305/100)
    offset += 2;
    buffer.writeInt16LE(302, offset);              // ve_nav: 3.02m/sec (302/100)
    offset += 2;
    buffer.writeInt16LE(0, offset);                // ve_slam: 0m/sec
    offset += 2;

    // 地向速度
    buffer.writeInt16LE(-50, offset);              // vd_gps1: -0.50m/sec (-50/100)
    offset += 2;
    buffer.writeInt16LE(-52, offset);              // vd_gps2: -0.52m/sec (-52/100)
    offset += 2;
    buffer.writeInt16LE(-51, offset);              // vd_nav: -0.51m/sec (-51/100)
    offset += 2;
    buffer.writeInt16LE(0, offset);                // vd_slam: 0m/sec
    offset += 2;

    // 纬度
    buffer.writeInt32LE(400000000, offset);        // lat_gps1: 40.0000000° (40*1e7)
    offset += 4;
    buffer.writeInt32LE(400000010, offset);        // lat_gps2: 40.0000010° (40.0000010*1e7)
    offset += 4;
    buffer.writeInt32LE(400000005, offset);        // lat_nav: 40.0000005° (40.0000005*1e7)
    offset += 4;
    buffer.writeInt32LE(0, offset);                // lat_slam: 0°
    offset += 4;

    // 经度
    buffer.writeInt32LE(1160000000, offset);       // lon_gps1: 116.0000000° (116*1e7)
    offset += 4;
    buffer.writeInt32LE(1160000010, offset);       // lon_gps2: 116.0000010° (116.0000010*1e7)
    offset += 4;
    buffer.writeInt32LE(1160000005, offset);       // lon_nav: 116.0000005° (116.0000005*1e7)
    offset += 4;
    buffer.writeInt32LE(0, offset);                // lon_slam: 0°
    offset += 4;

    // 高度
    buffer.writeInt16LE(100, offset);              // alt_gps1: 100m
    offset += 2;
    buffer.writeInt16LE(102, offset);              // alt_gps2: 102m
    offset += 2;
    buffer.writeInt16LE(101, offset);              // alt_nav: 101m
    offset += 2;
    buffer.writeInt16LE(0, offset);                // height_slam: 0m
    offset += 2;
    buffer.writeInt16LE(103, offset);              // height_baro: 103m
    offset += 2;

    // 空速
    buffer.writeInt8(25, offset++);                // ias_airspeed1: 25m/s
    buffer.writeInt8(26, offset++);                // ias_airspeed2: 26m/s
    buffer.writeInt8(0, offset++);                 // ias_airspeed3: 0m/s
    buffer.writeInt8(27, offset++);                // tas_airspeed1: 27m/s
    buffer.writeInt8(28, offset++);                // tas_airspeed2: 28m/s
    buffer.writeInt8(0, offset++);                 // tas_airspeed3: 0m/s

    // 融合标志
    buffer.writeInt8(1, offset++);                 // fuse_gps: 1 (融合)
    buffer.writeInt8(1, offset++);                 // fuse_airspeed: 1 (融合)
    buffer.writeInt8(0, offset++);                 // fuse_slam: 0 (不融合)

    // 转换为Base64
    const base64Data = buffer.slice(0, offset).toString('base64');

    // 返回组合导航数据对象
    return {
        "msg_id": 194,
        "cmd": 4,
        "data": base64Data
    };
};


// 生成传感器信息数据的函数
const generateSensorData = () => {
    // 创建二进制数据缓冲区 - 根据字段数量分配足够的空间
    // 每组数据需要 4 字节 (type:1 + status:1 + value1:2 + value2:2 = 6 字节)
    // 21组数据需要 21 * 6 = 126 字节
    const buffer = Buffer.alloc(126);
    let offset = 0;

    // 传感器类型定义
    const sensorTypes = [
        1,  // imu1
        2,  // imu2
        3,  // imu3
        11, // mag1
        12, // mag2
        13, // mag3
        21, // laser1
        22, // laser2
        23, // laser3
        31, // airspeed1
        32, // airspeed2
        33, // airspeed3
        41, // slam1
        51, // baro1
        52, // baro2
        61, // radar1
        62, // radar2
        71, // gps1
        72, // gps2
        73, // gps3
        74  // gpsheading
    ];

    // 为每个传感器类型生成数据
    sensorTypes.forEach(type => {
        // 状态值 (0: Health, 1: Degrade, 2: LostShort, 3: LostLong, 4: Fault)
        // 大多数传感器为正常状态，少数为其他状态
        let status = 0; // 默认为正常状态
        if (type % 10 === 3) { // 第3个传感器有问题
            status = Math.floor(Math.random() * 4) + 1; // 1-4之间的随机状态
        }

        // 根据传感器类型生成不同的值
        let value1 = 0;
        let value2 = 0;

        switch (Math.floor(type / 10)) {
            case 0: // IMU
                value1 = 100 + Math.floor(Math.random() * 50); // IMU温度 10.0-15.0℃
                value2 = 200 + Math.floor(Math.random() * 100); // IMU其他值
                break;
            case 1: // MAG
                value1 = 300 + Math.floor(Math.random() * 50); // 磁力计值
                value2 = 400 + Math.floor(Math.random() * 50); // 磁力计其他值
                break;
            case 2: // LASER
                value1 = 1000 + Math.floor(Math.random() * 9000); // 激光测距 1-10米
                value2 = Math.floor(Math.random() * 100); // 激光强度
                break;
            case 3: // AIRSPEED
                value1 = 2000 + Math.floor(Math.random() * 1000); // 空速 20-30m/s
                value2 = 1013 + Math.floor(Math.random() * 20); // 气压
                break;
            case 4: // SLAM
                value1 = 500 + Math.floor(Math.random() * 500); // SLAM位置X
                value2 = 500 + Math.floor(Math.random() * 500); // SLAM位置Y
                break;
            case 5: // BARO
                value1 = 10130 + Math.floor(Math.random() * 100); // 气压 1013.0-1023.0 hPa
                value2 = 250 + Math.floor(Math.random() * 50); // 高度 25.0-30.0米
                break;
            case 6: // RADAR
                value1 = Math.floor(Math.random() * 10000); // 雷达距离
                value2 = Math.floor(Math.random() * 360); // 雷达角度
                break;
            case 7: // GPS
                value1 = 8 + Math.floor(Math.random() * 5); // 卫星数量 8-12
                value2 = Math.floor(Math.random() * 100); // HDOP值 0-1.00
                break;
        }

        // 写入数据到缓冲区
        buffer.writeUInt8(type, offset);
        offset += 1;
        buffer.writeUInt8(status, offset);
        offset += 1;
        buffer.writeInt16LE(value1, offset);
        offset += 2;
        buffer.writeInt16LE(value2, offset);
        offset += 2;
    });

    // 转换为Base64
    const base64Data = buffer.toString('base64');

    // 返回传感器信息数据对象
    return {
        "msg_id": 194,
        "cmd": 3,
        "data": base64Data
    };
};

// 创建生成随机舵面数据的函数
const generateRandomServoData = () => {
    // 舵面类型定义
    const servoTypes = [
        1,  // 升降舵1
        2,  // 升降舵2
        11, // 方向舵1
        12, // 方向舵2
        21, // 副翼1
        22, // 副翼2
        23, // 副翼3
        24  // 副翼4
    ];

    // 创建二进制数据缓冲区
    const buffer = Buffer.alloc(8 * 6); // 8个舵面，每个6字节
    let offset = 0;

    // 为每个舵面类型生成随机数据
    servoTypes.forEach(type => {
        // 随机生成pwm值 (范围1000-2000)
        const pwm_fb = 1000 + Math.floor(Math.random() * 1000);
        const pwm_cmd = 1000 + Math.floor(Math.random() * 1000);
        const status = Math.floor(Math.random() * 2); // 0或1

        // 写入数据到缓冲区
        buffer.writeUInt8(type, offset);
        buffer.writeUInt16LE(pwm_fb, offset + 1);
        buffer.writeUInt16LE(pwm_cmd, offset + 3);
        buffer.writeUInt8(status, offset + 5);

        offset += 6;
    });

    // 转换为Base64
    const base64Data = buffer.toString('base64');

    // 返回新的servoData对象
    return {
        "msg_id": 194,
        "cmd": 2,
        "data": base64Data
    };
};

// 基本信息
const basicInfoData = {
    "msg_id": 10001,
    "control": "status",
    "uuid": "388b8ebb81814f0483263100a655c011",
    "info": "operation success",
    "code": 0,
    "success": true,
    "result": {
        "drone_heart_status": true,
        "drone_model": "V10R",
        "firmware_info": {
            "bat_serial_no0": "",
            "bat_serial_no1": "",
            "battery_fw": 0,
            "esc1_fw": 0,
            "esc2_fw": 0,
            "esc3_fw": 0,
            "esc4_fw": 0,
            "fc_fw": "V10_Autopilot_v324",
            "flightNum": 0,
            "fm_id": "V10FCGLS20420006",
            "gm_fw": 0,
            "gps_fw": 10019,
            "mag1_fw": 0,
            "mag2_fw": 21877,
            "mileage": 13701,
            "radio_fw": "F1000_rd_v3.5.3",
            "radio_id": "V1ORA2GLS2103",
            "reserve1": 0,
            "reserve2": 0,
            "reserve3": 0,
            "reserve4": 0,
            "sonar_fw": 0,
            "vision_fw": 0,
            "msg_id": 232
        },
        "payload": "V-TIRV12",
        "serial_status": "connected",
        "takeoff": 0,
        "unlock": 0
    }
}

let index = 0;

// 添加错误处理
const startServer = () => {
    try {
        const wss = new WebSocketServer({ port: PROXY_PORT });

        // 添加服务器级别的错误处理
        wss.on('error', (error) => {
            if (error.code === 'EADDRINUSE') {
                console.error(`端口 ${PROXY_PORT} 已被占用，请尝试使用其他端口`);
                process.exit(1);
            } else {
                console.error('WebSocket 服务器错误:', error);
            }
        });

        wss.on('connection', (clientWs, req) => {
            console.log('Client connected');

            // 解析客户端连接的 URL 参数
            const queryString = req.url?.split('?')[1];
            const params = new URLSearchParams(queryString);

            // 连接到目标服务器，使用完整的 URL 和参数
            const serverWs = new WebSocket(`${TARGET_URL}?${queryString}`);

            // 创建定时器
            let intervalId = null;

            // 当连接成功时开始定时发送数据
            serverWs.on('open', () => {
                console.log('Connected to target server');



                // 立即发送一次数据
                if (clientWs.readyState === WebSocket.OPEN) {
                    // 发送初始数据
                    clientWs.send(JSON.stringify(mockData));
                    // 发送启动状态数据
                    clientWs.send(JSON.stringify(startupStateData));
                }

                // 设置定时器，每秒发送一次数据
                intervalId = setInterval(() => {
                    if (clientWs.readyState === WebSocket.OPEN) {
                        try {
                            // 发送初始数据
                            clientWs.send(JSON.stringify(mockData));
                            // 发送启动状态数据
                            clientWs.send(JSON.stringify(startupStateData));
                            // 发送动力电池充电器状态数据
                            clientWs.send(JSON.stringify(chargerStateData));
                            // 发送航电电池充电器状态数据
                            clientWs.send(JSON.stringify(batteryChargerStateData));
                            // 发送发动机转速数据
                            clientWs.send(JSON.stringify(engineSpeedData));
                            // 发送雷达数据
                            clientWs.send(JSON.stringify(radarData));
                            // 发送发动机温度和燃油压力数据
                            clientWs.send(JSON.stringify(engineTempAndFuelData));
                            // 发送燃油与航时数据
                            clientWs.send(JSON.stringify(fuelAndFlightTimeData));
                            // 发动充电器状态2数据
                            clientWs.send(JSON.stringify(chargerState2Data));
                            // 发送电池状态数据
                            clientWs.send(JSON.stringify(batteryStateData));
                            // 发送电池温度与电量数据
                            clientWs.send(JSON.stringify(batteryTempAndSOCData));
                            // 发送动态生成的舵面信息数据
                            clientWs.send(JSON.stringify(generateRandomServoData()));
                            // 发送组合导航数据
                            clientWs.send(JSON.stringify(generateNavData()));
                            // 发送传感器信息数据
                            clientWs.send(JSON.stringify(generateSensorData()));



                            index += 1;


                            //    主控副控切换
                            if (index < 20) {
                                if (index % 2 === 0) {
                                    // 未接管 // {"device_id": 2,"flag": 0 }
                                    clientWs.send(JSON.stringify(takeoverData2));
                                } else {
                                    // 发送接管状态数据 已接管 // {"device_id": 1,"flag": 1 }
                                    clientWs.send(JSON.stringify(takeoverData));
                                }
                            } else {
                                clientWs.send(JSON.stringify(takeoverData3));

                            }


                        } catch (error) {
                            console.error('Error sending mock data:', error);
                        }
                    } else {
                        console.log('Client connection not open, readyState:', clientWs.readyState);
                    }
                }, 1000);
            });

            // 处理来自目标服务器的消息
            serverWs.on('message', (data) => {
                try {
                    // 解析数据并处理
                    const receivedData = JSON.parse(data.toString());
                    /* 
                    {
                        "msg_id": 10000,
                        "control": "status",
                        "uuid": "b7dfcbcadca44d43b1077b2971338be6",
                        "body": null
                    }
                    */

                    // 如果接收到的control是status，就返回基本信息
                    if (receivedData.control === 'status') {
                        // 发送基本信息数据
                        clientWs.send(JSON.stringify(basicInfoData));
                    }




                    // 转发消息给客户端
                    clientWs.send(data.toString());



                } catch (error) {
                    console.error('Error handling server message:', error);
                }
            });

            // 处理来自客户端的消息
            clientWs.on('message', (data) => {
                try {
                    console.log('Received from client:', data.toString());
                    // 转发到目标服务器
                    if (serverWs.readyState === WebSocket.OPEN) {
                        serverWs.send(data.toString());
                    }
                } catch (error) {
                    console.error('Error handling client message:', error);
                }
            });

            // 错误处理
            clientWs.on('error', console.error);
            serverWs.on('error', console.error);

            // 修改关闭连接处理，清除定时器
            clientWs.on('close', () => {
                console.log('Client disconnected');
                if (intervalId) {
                    clearInterval(intervalId);
                }
                if (serverWs.readyState === WebSocket.OPEN) {
                    serverWs.close();
                }
            });

            serverWs.on('close', () => {
                console.log('Server disconnected');
                if (intervalId) {
                    clearInterval(intervalId);
                }
                if (clientWs.readyState === WebSocket.OPEN) {
                    clientWs.close();
                }
            });
        });

        console.log(`WebSocket 代理服务器运行在端口 ${PROXY_PORT}`);
        console.log(`转发目标地址: ${TARGET_URL}`);
    } catch (error) {
        console.error('启动服务器时发生错误:', error);
        process.exit(1);
    }
};

startServer();
